本节主要讲计算机的编码存储格式和相应的变换。
## 机器数和真值
先来说两个概念:
- 机器数:在计算机中的二进制表示形式,是可以表示符号的,比如正负数
- 真值: 是计算机内真正的那个值,因为一般有一个`bit`表示符号位,所以看到的和实际表示并不一致
https://blog.csdn.net/qq_48486897/article/details/106653164
# 计算机所有存储都是补码,得到结果也是补码
a = 3
b = 5
print("3&b = {0}".format(a&b))
print("-1 & -2 = {0}".format(-1&-2))
print("-2 & 6 = {0}".format(-2 & 6))
# 位运算在乘除法中的应用
print(" 1x2={0}".format(1<<1))
print(" 1x16={0}".format(1<<4))
print(" -10x4={0}".format(-10<<2))
print(" -40/4={0}".format(-40>>2))
# 二进制表示法
print("10={0}".format(bin(10)))
print("-10={0}".format(bin(-10)))
# 2. 原码
- 符号位加上真值的绝对值
```angularjs
(+1)原码 = 0000 0001
(-1)原码 = 1000 0001
八位取值范围是[1111 1111 - 0111 1111] = [-127 - 127]
```
# 3. 反码
- 正数的反码是其本身
- 负数的反码是在原码的基础上,符号位不变,其余各位取反
```angularjs
[+1] = [0000 0001]原码 = [0000 0001]反码
[-1] = [1000 0001]原码 = [1111 1110]反码
```
# 4. 补码
- 正数的补码是本身
- 负数的补码是原码基础上,符号位不变,各位取反,然后加1,即反码+1
# 5. 移码
- 补码的符号位取反
# 5. 为什么使用
- 1-1的问题
```angularjs
(1 - 1)原码表示 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
(1 - 1)反码表示 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
(1 - 1)补码表示 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补
```
- -128只是一个表示方法,是-0表示的-128,不是计算出来的,计算出来的是错误的,
```angularjs
[1000 0000]补码 = [0000 0000]原码 = 错误
```
- 补码,修复了0的两个表示方法带来的问题,还可以表示一个最低位,所以八位二进制表示范围是[-128,127]
# 编码问题
- 为什么需要编码
- 计算机本质上只能表示二进制
- 如何用一长串二进制表示复杂的信息
- 编码简史
- 二进制:
- 数字->字符->数字
- 'a' -> 97 编码和解码
- 第一阶段: ASCII
- 第二阶段:百花齐放,GB2312,GBK, BIG5 Latin1, ISO-8859-1, JIS, ANSI...
- Latin1(ISO-8859-1)
- 中国GBxxx
- 韩国台湾Big5
- 日本JIS
- ANSI-MBCS(Muilti-Bytes Charecter Set,多字节字符集)
- Unicode+ISO
# 编码表示法
- ASCII-American Standard Code for Information Interchange
- 所有的控制字符(比如CR回车、DEL删除等)编码在0-31范围以及127中。
- 把所有的标点符号,英文大小写全部放在32-126范围中。
- 防止以后出现需要补充的情况,把128-255位这么多位置留出来,
- 0xxxx xxxx, 高位为0
- Latin1
- 0-127的所有位置不动,那么可以兼容ASCII,二进制位0xxx xxxx
- 128-255位置全部用完,二进制位1xxx xxxx
- 128-159之间为控制字符,
- 160-255位文字符号,
- 其中包括了西欧语言、希腊语、泰语、阿拉伯语、希伯来语
- 欧元符号
- GBXXXXXXXXX
- GB2312
- 如果一个字节中第一位为0,那么这就是一个ASCII字符。
-如果一个字节中第一位为1,那么这个是汉字,认定需要2个字节才表示一个编码的文字。
- 这个码表中包含汉字6763个和非汉字图形字符682个。
- 还有很多的空间没有用到,索性全部预留了吧。
- 0xxxxxxx:表示为ASCII字符
-1xxxxxxx 1xxxxxxx:表示为汉字
- GBK
- 在GB2312基础上添加汉字
- 兼任GB2312和ASCII
- 0xxxxxxx:表示为ASCII字符
- 1xxxxxxx xxxxxxxx:表示为汉字
- GB18030
- 2/4位混编
- Unicode
- 只是一个码表,具体实现没有规定
- 0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符
- 中文的编码范围为4E00-9FCF,其中9FC4-9FCF之间的区间没有使用
- 上述区间全部是汉字,不包含全角字符,不包含特殊文字
- UTF=UnicodeTransformationFormat
- UTF-8
0x0000~0x007F (0 ~ 127) 1字节 0xxxxxxx
0x0080~0x07FF(128 ~ 2047) 110xxxxx 10xxxxxx
0x0800~FFFF(2048 ~ 65535) 3字节 1110xxxx 10xxxxxx 10xxxxxx
0x10000~1FFFFFF(65536 ~ 2097152) 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0x2000000~0x3FFFFFF 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0x4000000~0x7FFFFFFF 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- UTF-16, 32
- UTF-16是早期Unicode遗留产物
- UTF-32浪费空间
- UCS-2
- UCS=UniversalCharacterSet,通用字符集
- UCS-2与Unicode相同
- 采用2个字节,定长的表示每一个字符,所以总计可以表示2^16个字符
- UCS-4
- 第一个字节:表示组(group),最高位为0,则有128个。
- 第二个字节:表示平面(plane),256个。
- 第三个字节:表示行(row),256个。
- 第四个字节:表示码位(cell),256个
- 如果UCS-4前两个字节为0, 则就是CUS-2
# 概念解释
- 大尾(BigEndian) 小尾(LittleEndian)
- "汉" -> 6C49
- 6C49 -> BigEndian
- 496C -> LittleEndian
- BOM
- UTF-8 无字节顺序问题
- UTF-16会出现问题:
- "奎" -> 594E
- "乙" -> 4E59
- BOM-ByteOrderMark
- "ZERO WIDTH NO-BREAK SPACE" -> FEFF, 在UCS中不存在
- FEFF->BigEndian
- FFFE->LittleEndian
- UTF-8 用来表示编码, FEFF的UTF-8编码是EF BB BF, 用来表示此后编码是UTF-8编码
# Python的编码问题
- str
- bytes
- bytearray
>>> b = bytes.fromhex('E4 B8 AD')
>>> b
b'\xe4\xb8\xad'
>>> b.decode('utf-8')
'中'
>>> str(b)
"b'\\xe4\\xb8\\xad'"
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(65)
'A'
>>> chr(20013)
'中'
- len的单位是字符,不是字节
- python文件默认utf-8编码,如果特殊需要,需要声明
- 放在第一行,或者第二行
- ```# ‐*‐ coding: windows‐1252 ‐*‐```
- 读写文件默认utf-8, 可以指定
- code point方式比较字符串,可能会带来问题
- 重音符号的表示
- 使用 unicodedata.normalize 函数
- Python源码中出现了解码错误,那么会产生SyntaxError异常
- 其他情况下,如果发现编码解码错误,那么会产生UnicodeEncodeError, UnicodeDecodeError异常
# 参考资料
- https://www.cnblogs.com/jessonluo/p/4800331.html
- https://blog.csdn.net/xuejianhui/article/details/52576771
- http://tools.jb51.net/table/gb2312
-